Skip to content

Conversation

@spall
Copy link
Collaborator

@spall spall commented Dec 18, 2025

Implements support for groupshared argument attribute.
Closes #7969

spall added 4 commits December 3, 2025 16:37
get compiler to error when types aren't exactly the same + arg not groupshared

bug fix

fix test

disallow groupshared param in export/noinline funcs

first check if there are attrs

remove accidental change

tests
@github-actions
Copy link
Contributor

github-actions bot commented Dec 18, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 60a1c8568b405bbe9f47ab0431f627ef64988cc4 8511e4efe9344b5a326a358463f14582da38fe07 -- lib/HLSL/HLLegalizeParameter.cpp tools/clang/include/clang/AST/Decl.h tools/clang/lib/AST/HlslTypes.cpp tools/clang/lib/AST/MicrosoftMangle.cpp tools/clang/lib/CodeGen/CGHLSLMS.cpp tools/clang/lib/Sema/SemaDeclAttr.cpp tools/clang/lib/Sema/SemaHLSL.cpp tools/clang/lib/Sema/SemaOverload.cpp
View the diff from clang-format here.
diff --git a/tools/clang/lib/CodeGen/CGHLSLMS.cpp b/tools/clang/lib/CodeGen/CGHLSLMS.cpp
index ee7724c3..200f62f6 100644
--- a/tools/clang/lib/CodeGen/CGHLSLMS.cpp
+++ b/tools/clang/lib/CodeGen/CGHLSLMS.cpp
@@ -1247,7 +1247,7 @@ unsigned CGMSHLSLRuntime::AddTypeAnnotation(QualType Ty,
 
   if (const ReferenceType *RefType = dyn_cast<ReferenceType>(Ty))
     Ty = RefType->getPointeeType();
-  
+
   // Get size.
   llvm::Type *Type = CGM.getTypes().ConvertType(paramTy);
   unsigned size = dataLayout.getTypeAllocSize(Type);
diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp
index 56bb346c..07fbd523 100644
--- a/tools/clang/lib/Sema/SemaHLSL.cpp
+++ b/tools/clang/lib/Sema/SemaHLSL.cpp
@@ -14485,7 +14485,7 @@ void Sema::DiagnoseHLSLDeclAttr(const Decl *D, const Attr *A) {
           switch (A->getKind()) {
           case clang::attr::HLSLGroupShared: {
             Diag(A->getLocation(), diag::err_hlsl_varmodifiersna)
-	         << "groupshared"
+                << "groupshared"
                 << "export/noinline"
                 << "parameter";
             return;
  • Check this box to apply formatting changes to this branch.

Copy link
Member

@hekota hekota left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, I just have a few comments and suggestions/nits.

groupshared uint16_t SharedData;

void fn1(groupshared half Sh) {
// expected-note@-1{{candidate function not viable: no known conversion from '__attribute__((address_space(3))) uint16_t' to '__attribute__((address_space(3))) half &' for 1st argument}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since references are not supported in HLSL, should we make sure the error includes half and not half &?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically in this case it is a reference.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that internally it is a reference, but for the user half & is confusing because references are not part of the language. It would be good to use ParamType.getNonReferenceType() instead of ParamType in the error message, the same way is it used in the ASTContext::hasSameUnqualifiedType call.

groupshared uint16_t SharedData;

void fn1(groupshared half Sh) {
// expected-note@-1{{candidate function not viable: 1st argument ('half') is in address space 0, but parameter must be in address space}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// expected-note@-1{{candidate function not viable: 1st argument ('half') is in address space 0, but parameter must be in address space}}
// expected-note@-1{{candidate function not viable: 1st argument ('half') is in address space 0, but parameter must be in address space 3}}

Comment on lines +3 to +6
RWStructuredBuffer<uint4> Out : register(u0);

groupshared uint16_t SharedData;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these needed for the test to work?


void fn2() {
fn1(SharedData);
// expected-warning@-1{{assing groupshared variable to a parameter annotated with inout. See'groupshared' parameter annotation added in 202x}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// expected-warning@-1{{assing groupshared variable to a parameter annotated with inout. See'groupshared' parameter annotation added in 202x}}
// expected-warning@-1{{Passing groupshared variable to a parameter annotated with inout. See'groupshared' parameter annotation added in 202x}}


// CHECK-LABEL: @"\01?fn1@@YAXAGAU?$Shared@H@@@Z"
// CHECK: [[D:%.*]] = alloca double, align 8
// CHECK: [[A:%.*]] = getelementptr inbounds %"struct.Shared<int>", %"struct.Shared<int>" addrspace(3)* %Sh, i32 0, i32 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a CHECK for %Sh before its first use? Where does it come from?

fn2(11.xxxx);
}

void fn(groupshared float4 Arr[2]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add a CHECK for the groupshared signature functions as well to see how it differs. Also, I think the CHECK-DAG labels in this test should be changed to CHECK (or CHECK-LABEL for the function definitions) because the order matters.

Comment on lines +5 to +6
// mangling changes added the first G
// CHECK-LABEL: @"\01?fn1@@YAXAGAG@Z"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// mangling changes added the first G
// CHECK-LABEL: @"\01?fn1@@YAXAGAG@Z"
// Make sure the groupshared parameter annotation is reflected in the mangled function signature (the first G)
// CHECK-LABEL: @"\01?fn1@@YAXAGAG@Z"

The comment did not make sense to me out of context.

Comment on lines +941 to +949
while (pAttributes != nullptr) {
switch (pAttributes->getKind()) {
case AttributeList::AT_HLSLGroupShared:
return true;
default:
break;
}
pAttributes = pAttributes->getNext();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
while (pAttributes != nullptr) {
switch (pAttributes->getKind()) {
case AttributeList::AT_HLSLGroupShared:
return true;
default:
break;
}
pAttributes = pAttributes->getNext();
}
while (pAttributes != nullptr) {
if (pAttributes->getKind() == AttributeList::AT_HLSLGroupShared)
return true;
pAttributes = pAttributes->getNext();
}

Comment on lines +14482 to +14495
if (!PVD->hasAttrs())
continue;
for (Attr *A : PVD->getAttrs()) {
switch (A->getKind()) {
case clang::attr::HLSLGroupShared: {
Diag(A->getLocation(), diag::err_hlsl_varmodifiersna)
<< "groupshared"
<< "export/noinline"
<< "parameter";
return;
break;
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!PVD->hasAttrs())
continue;
for (Attr *A : PVD->getAttrs()) {
switch (A->getKind()) {
case clang::attr::HLSLGroupShared: {
Diag(A->getLocation(), diag::err_hlsl_varmodifiersna)
<< "groupshared"
<< "export/noinline"
<< "parameter";
return;
break;
}
}
}
if (PVD->hasAttr<HLSLGroupSharedAttr>())
Diag(A->getLocation(), diag::err_hlsl_varmodifiersna)
<< "groupshared"
<< (IsExportAttr ? "export : noinline")
<< "parameter";
return;
}

Comment on lines +1461 to +1462
if (!isModifierIn() && !isModifierOut())
return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::Ref);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to have an explicit bit for the groupshared modifier on the param decl, the same way it is for out instead of assuming that it is groupshared when it's not in or out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

Implement support for groupshared arguments in 202x

2 participants